import _ from 'lodash'

export const $bgPath = 'https://612d-a-5grky2ni98adbbcf-1312526829.tcb.qcloud.la/bg'
export const $serverUrl = 'http://106.52.172.108:8080/xq-cloud'
// export const $serverUrl = '/api' // 配合 跨域 manifest.json h5.devServer.proxy
import { modelSet, modelAssign, modelGet } from '../store/modelOpt'
import { router } from '../router'
import dayjs from 'dayjs'

export * from '../store/modelOpt'
export * from './utilUniCloud'

const globalData = {
  loginPromise: null,// 登录promise
  appInfoPromise: null,// 整个小程序的关键参数
}

export function setGlobalData(key, val){
  globalData[key] = val
}

export function getGlobalData(key){
  return globalData[key]
}

export function log(obj){
  if (_.isPlainObject(obj) || _.isArray(obj)) {
    console.log(JSON.stringify(obj, null, '\t'))
  } else {
    console.log(obj)
  }
}

/**
 * 展示提示信息
 * @param title
 * @param time
 * @returns {Promise<any>}
 */
export function message(title = '', time = 1500){
  return new Promise((resolve, reject) => {
    uni.showToast({
      title: title,
      icon: 'none',
      mask: false,
      duration: time,
    })
    let timeId = setTimeout((res) => {
      resolve()
      clearTimeout(timeId)
      timeId = null
    }, time)
  })
}

/**
 * 跳转
 * @param path string|object
 * @param type string push replace replaceAll
 */
export function linkTo(path, type = 'push'){
  let obj = {}
  if (path) {
    if (_.isString(path)) {
      obj.path = path
    } else if (_.isObject(path)) {// {path:'',query:{}}
      _.merge(obj, path)
    }
    if (obj.path) {
      router[type](obj)
    }
  }
}

/**
 * 后退
 */
export function linkBack(){
  router.back()
}

/**
 * 封封微信的的request
 */
export function request(url, data = {}, method = 'GET'){
  let token = uni.getStorageSync('token')
  let admin_id = modelGet('appInfo.admin_id')
  return new Promise(function (resolve, reject){
    uni.request({
      url: $serverUrl + url,
      data: data,
      method: method,
      header: {
        'Content-Type': 'application/json',
        'X-Access-Token': token, // 跨域需要设置 add_header Access-Control-Allow-Headers
      },
      success: async (res) => {// {cookies header data errMsg}
        log(`### ${url}\n### ${JSON.stringify(data)}`)
        if (res.statusCode === 200) {
          if (res.data.code === 401) {
            //   message: "token验证失败" 异地登录|token失效
            //   // 跳转个人中心页面 (重复跳转会导致路由紊乱)
            message('请先登录~').then((res) => {
              // if (router.currentRoute.path !== '/pages2/user/index') {
              //   linkTo(`/pages2/user/index`)
              // }
            })
            reject({
              data: res.data.result,
              status: res.data.code,
              message: res.data.message,
              ...res.data,
            })
          } else if (res.data.code === 'N10105') {
            // "登录超时，请重新登录"
            //  需要登录后才可以操作 -> 自动获取code重新登录即可 (一般系统是跳转登录界面) (死循环)
            try {
              await login_wx()
            } catch (e) {
              reject({
                data: res.data.result,
                status: res.data.code,
                message: '登录超时,请重新登录~',
                ...res.data,
              })
            }
          } else if (res.data.code === 200) {// 后台代码逻辑通过并正常返回数据
            log(res.data.result)
            resolve({
              data: res.data.result,
              status: res.data.code,
              message: res.data.message,
              ...res.data,
            })
          } else {
            console.log('!!!请求错误', res)
            reject({
              data: res.data.result,
              status: res.data.code,
              message: res.data.message,
              ...res.data,
            })
          }
        } else {
          reject({ message: '服务器访问错误' })
        }
      },
      fail: (err) => {
        reject({ message: '服务器访问失败', ...err })
      },
    })
  })
}

export function requestGet(url, data = {}){
  return request(url, data, 'GET')
}

export function requestPost(url, data = {}){
  return request(url, data, 'POST')
}

export function requestDelete(url, data = {}){
  return request(url, data, 'DELETE')
}

/**
 * 获取微信code
 */
export function getWXCode(){
  return new Promise((resolve, reject) => {
    // #ifdef APP-PLUS
    weixinAuthService.authorize(function (res){
      resolve(res.code)
    }, function (err){
      console.log(err)
      reject(new Error('微信登录失败'))
    })
    // #endif
    // #ifdef MP-WEIXIN
    uni.login({
      provider: 'weixin',
      success(res){
        resolve(res.code)
      },
      fail(err){
        reject(new Error('微信登录失败'))
      },
    })
    // #endif
    // #ifdef H5
    reject(new Error('微信登录失败'))
    // #endif
  })
}

/*
* 获取手机号
* */
export async function getPhone(e){
  return new Promise((resolve, reject) => {
    if (e.type === 'getphonenumber') {
      console.log(`e.detail`, e.detail)
      let encryptedData = e.detail.encryptedData // 包括敏感数据在内的完整用户信息的加密数据
      let iv = e.detail.iv // 加密算法的初始向量，详细见加密数据解密算法
      let errMsg = e.detail.errMsg
      if (iv == null || encryptedData == null) { // 获取失败
        //  /fail/.test(errMsg)  "getPhoneNumber:fail Error: 该 appid 没有权限"    获取手机号失败,需要用户提交
        message('获取失败,请通过授权以确认您的身份~')
        reject({ msg: '事件错误' })
      } else {// 小程序 成功获取手机号
        requestUtilPost('/weichat/getPhone', {
          encryptedData: encryptedData,
          iv: iv,
        }).then(({ body }) => {// 成功匹配
          console.log(`data`, body)
          resolve(body)
        }).catch((err) => {
          // message('登录失败,请稍后重试,谢谢!')
          console.log(`err`, err)
          reject({ msg: '请求错误' })
        })
      }
    } else {
      reject({ msg: '事件错误' })
    }
  })
}

/**
 * 获取日期的前后七天列表
 * @param chooseDate
 * @returns {{date: *|string, week, value: *|string}[]}
 */
export function dateListGet(chooseDate){
  let res = _.times(7, (i) => {
    let dayInfo = dayjs(chooseDate).add(i - 3, 'day')
    return {
      date: dayInfo.format('DD'),
      week: ['日', '一', '二', '三', '四', '五', '六'][dayInfo.day()],
      value: dayInfo.format('YYYY-MM-DD'),
      disable: dayInfo.unix() < dayjs().unix(),// 是否在当前时间之前
    }
  })
  return res
}

export function timeListGet(chooseDate){
  let res = []
  let dateBegin = dayjs(chooseDate)
  _.times(24, (i) => {
    let beginTime = `${i}`.padStart(2, '0') + ':00'
    let value = chooseDate + ' ' + beginTime
    res.push({
      key: i,
      begin: dateBegin.add(i, 'hour').format('YYYY-MM-DD HH:mm:ss'),
      end: dateBegin.add(i + 1, 'hour').format('YYYY-MM-DD HH:mm:ss'),
      beginTime: dateBegin.add(i, 'hour').format('HH:mm'),
      endTime: dateBegin.add(i + 1, 'hour').format('HH:mm'),
      disable: dayjs(value).unix() < dayjs().unix(),// 是否在当前时间之前
    })
  })
  console.log(`res`, res)
  return res
}

/*
* 根据token获取用户信息
* 或者重置用户信息
* */
export function userInfoGet(){
  return requestGet('/common/sys/user/getUserInfo').then(({ data }) => {
    modelAssign('userInfo', data)
    return data
  }).catch((e) => {
    console.log(`e`, e)
    modelSet('userInfo', {
      id: undefined,
    })
  })
}

export async function login_wx(info){
  let appid = 'wx63ba6e59b5cd0fb7'
  let code = await getWXCode()
  let { data: openIdData } = await requestGet(`/common/wxuser/${appid}/login`, { appid, code })
  return new Promise(function (resolve, reject){
    uni.request({
      url: $serverUrl + '/common/sys/user/login',
      data: {
        'appId': appid,
        'captcha': '',
        'checkKey': '',
        'openId': openIdData.openid,
        'username': info.username,
        'password': info.password,
        'userType': 2,
      },
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'token': '',// 初次登录无token
      },
      success: async (res) => {// {cookies header data errMsg}
        console.log('sysLogin success', res)
        let token = _.get(res, 'data.result.token')
        if (token) {
          uni.setStorageSync('token', token)
          modelSet('userInfo', res.data.result.userInfo)
          modelSet('sysAllDictItems', res.data.result.sysAllDictItems)
          modelSet('departs', res.data.result.departs)
          modelSet('customer', res.data.result.customer)
          linkBack()
        } else {
          console.error(`login no token`, res)
        }
        // util.userInfoGet()
      },
      fail: (err) => {
        console.error('sysLogin failed', err)
        reject({ message: '服务器访问失败', ...err })
      },
    })
  })
}

export function login_h5(){
  return new Promise(function (resolve, reject){
    uni.request({
      url: $serverUrl + '/test/weichatMiniprogramLogin',
      data: { weichatId: 'oUcox5TwxvxSlPUJyr40jO3vKtyQ' },
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'token': '',// 初次登录无token
      },
      success: async (res) => {// {cookies header data errMsg}
        console.log('sysLogin success', res)
        let token = res.header['X-Auth-Token'] || res.header['x-auth-token']
        if (token) {
          uni.setStorageSync('token', token)
        } else {
          console.error(`login no token`, res)
        }
        modelSet('userInfo', res.data.body)
        resolve(res.data.body)
      },
      fail: (err) => {
        console.error('sysLogin failed', err)
        reject({ message: '服务器访问失败', ...err })
      },
    })
  })
}

/*
* 业务:微信登录
* */
export function uniLogin_wx(){
  return getWXCode().then((code) => {
    console.log(`code`, code)
    return uniCloud.callFunction({
      name: 'user-center',
      data: {
        action: 'loginByWeixin',
        params: {
          code,
        },
      },
    })
  }).then((res) => {// { result: { userInfo : {} } }
    console.log(`loginWX res`, res)
    message('登录成功~')
    if (res.result.code === 0) {
      let userInfo = res.result.userInfo
      // uni.setStorageSync('uni_id_token', res.result.token)
      // uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)
      modelSet('userInfo', userInfo)
    }
  }).catch((e) => {
    console.error('loginWX e', e)
    message('登录失败，请稍后再试~')
  }).finally(async () => {
    // if (this.userInfo._id) {
    //   // let pageInfoRes = await this.$util.uniDB('juzi-user-page').where({ userId: this.userInfo._id }).get()
    //   // console.log(`pageInfo`, pageInfoRes)
    //   // pageNumber = _.get(pageInfoRes, 'result.data[0].pageNumber') || 1
    // }
  })
}

/*
* 业务:h5登录
* */
export function uniLogin_h5(){
  return uniCloud.callFunction({
    name: 'user-center',
    data: {
      action: 'checkToken',
      params: {},
    },
  }).then((res) => {
    if (res.result.code === 0) {
      let userInfo = res.result.userInfo
      // uni.setStorageSync('uni_id_token', res.result.token)
      // uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)
      modelSet('userInfo', userInfo)
    }
    if (res.result.err) {
      console.error(res.result.message)
    }
  }).catch((e) => {
    console.error(`user-center`, e)
  })
}

/**
 * 微信支付
 * @param config {order_on,type} 3 购买期限卡  2 充值余额 1 预定 5 开通会员
 * @returns {Promise<unknown>}
 */
export async function payWx(config){
  let code = await getWXCode()
  return new Promise((resolve, reject) => {
    requestPost('/Wecat/index', {
      order_on: config.order_on,
      type: config.type,
      code: code,
    }).then(({ data }) => {
      console.log(`data`, data)
      wx.requestPayment({
        appid: data.appId,
        timeStamp: data.timeStamp,
        nonceStr: data.nonceStr,
        package: data.package,
        signType: data.signType,
        paySign: data.paySign,
        success(res){
          console.log(res)
          if (res.errMsg == 'requestPayment:ok') {
            message('支付成功~')
            resolve()
          } else {
            reject(res)
          }
        },
        fail(e){
          console.log(`e`, e)
          // requestPayment:fail cancel 取消支付
          message('支付失败~')
          reject(e)
        },
      })
    }).catch((e) => {
      console.log(`e`, e)
      reject(e)
    })
  })

}

export function locationOpen(info){
  console.log(`info`, info)
  if (info.lat && info.lng) {
    uni.openLocation({
      latitude: Number(info.lat),
      longitude: Number(info.lng),
      name: info.name || info.room_name,
      address: info.address,
      scale: 18,
      success: function (){
        console.log('success')
      },
    })
  } else {
    message('地址信息有误~')
  }
}

export function phoneCall(info){
  console.log(`info`, info)
  if (info.mobile) {
    uni.makePhoneCall({
      phoneNumber: info.mobile, //仅为示例
    })
  } else {
    message('手机号为空~')
  }
}

/*
* 判断此页面是否要展示菜单,判断url是否在menuList列表中
* */
export function isMenuShow(path){
  let menuList = modelGet('appInfo.menuList')
  return _.some(menuList, (n, i) => {
    return n.tabbar_url === path
  })
}

export function richTextDeal(content = ''){
  return (content || '').replace(/\<img/gi, '<img class="rich-img" ')
}

/**
 * 获取用户当前位置信息
 */
export function getUserLocation(){
  return new Promise((resolve, reject) => {
    if (modelGet('env.dev')) {// 调试
      resolve({ 'latitude': 32, 'longitude': 118, 'city': '北京', 'province': '北京' })
      return
    }
    if (modelGet('userLocation').latitude) {
      resolve(modelGet('userLocation'))
      return
    }
    // 会弹框授权
    uni.getLocation({
      type: 'gcj02',//  wgs84 gcj02 https://developers.weixin.qq.com/miniprogram/dev/component/map.html
      success: (res) => {
        console.log(`success`, res)// {latitude,longitude}
      },
      fail: (e) => {
        console.log(`fail`, e)
      },
      complete: (res) => {
        console.log(`complete`, res)
        if (res.latitude) {
          requestPost('/index/address', {
            lat: res.latitude,
            lng: res.longitude,
          }).then(({ data }) => {
            // //  res
            // errMsg: "getLocation:ok",
            // horizontalAccuracy: undefined,
            // latitude: 32.056305,
            // longitude: 118.801654,
            // verticalAccuracy: 0,
            // // data
            // "city": "南京市",
            // "province": "江苏省"
            modelSet('userLocation', { ...res, ...data })
            resolve({ ...res, ...data })
          }).catch((e) => {
            modelSet('userLocation', res)
            resolve(res)
          })
        } else {
          resolve({})
        }
      },
    })
  })
}

export function toLogin(){
  if (modelGet('userInfo.id')) {
    return false
  } else {
    modelSet('loginModalVisible', true)
    // message('请先登录~').then((res) => {
    //   linkTo('/pages2/user/index')
    // })
    return true
  }
}

export function shareInfo(){
  return {
    title: modelGet('appInfo.store_name'),
    imageUrl: modelGet('share.image_url'),
    path: '/pages/index/index',
  }
}

/**
 * 订阅消息
 */
export function subTemplate(){
  return new Promise((resolve, reject) => {
    if (modelGet('env.h5')) {
      resolve()
      return
    }
    requestPost('/store/Template', {}).then(({ data }) => {
      console.log(`/store/Template data`, data)
      uni.requestSubscribeMessage({
        tmplIds: _.map(data, 'template_id'),
        success(res){
          console.log(`res`, res)
        },
        fail(e){
          console.log(`e`, e)
          message(e.errMsg || '订阅失败')
        },
        complete(res){
          console.log(`res`, res)
          resolve()
        },
      })
    }).catch((e) => {
      message(e.message)
    })
  })

}
